<?php

namespace App\Util;

use App\Models\Doctor;
use Gregwar\Captcha\CaptchaBuilder;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Str;
use App\User;
use Illuminate\Support\Facades\DB;
use PhpParser\Node\Stmt\DeclareDeclare;

class Tool
{
    /**
     * 获取真实IP地址
     * @return array|false|mixed|string
     */
    public static function getRealIp()
    {
        $ip = false;
        if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown")) {
            $ip = getenv("HTTP_CLIENT_IP");
        } else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown")) {
            $ips = explode(", ", getenv("HTTP_X_FORWARDED_FOR"));
            if ($ip) {
                array_unshift($ips, $ip);
                $ip = false;
            }
            $ipscount = count($ips);
            for ($i = 0; $i < $ipscount; $i++) {
                if (!preg_match("/^(10|172\.16|192\.168)\./i", $ips[$i])) {
                    $ip = $ips[$i];
                    break;
                }
            }
        } else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown")) {
            $ip = getenv("REMOTE_ADDR");
        } else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown")) {
            $ip = $_SERVER['REMOTE_ADDR'];
        } else {
            $ip = "unknown";
        }
        return Tool::isIp($ip) ? $ip : "unknown";
    }

    /**
     * @param $dt
     * @return mixed
     * 开始推送
     *         $dt["user_id"] =3 ;
    $dt["title"] = "测试内推";
    $dt["content"] = "测试内推";
     */
    public static function startPush($dt)
    {
        $url = "https://mains.yiluchuyuan.com/api/pushmessage/startAliPush";
        $b = json_encode($dt);
        $res = self::postCurl($url, $b, []);
        return $res;
    }

    public static function postCurl($url, $body, $header, $type = "POST")
    {
        //1.创建一个curl资源
        $ch = curl_init();
        //2.设置URL和相应的选项
        curl_setopt($ch, CURLOPT_URL, $url);//设置url
        //1)设置请求头
        //array_push($header, 'Accept:application/json');
        array_push($header,'Content-Type:application/json');
        //array_push($header, 'http:multipart/form-data');
        //设置为false,只会获得响应的正文(true的话会连响应头一并获取到)
        curl_setopt($ch, CURLOPT_HEADER, 0);
//		curl_setopt ( $ch, CURLOPT_TIMEOUT,5); // 设置超时限制防止死循环
        //设置发起连接前的等待时间，如果设置为0，则无限等待。
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
        //将curl_exec()获取的信息以文件流的形式返回，而不是直接输出。
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        //2)设备请求体
        if (strlen($body) > 0) {
            //$b=json_encode($body,true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $body);//全部数据使用HTTP协议中的"POST"操作来发送。
        }
        //设置请求头
        if (count($header) > 0) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }
        //上传文件相关设置
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 对认证证书来源的检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);// 从证书中检查SSL加密算
        //3)设置提交方式
        switch ($type) {
            case "GET":
                curl_setopt($ch, CURLOPT_HTTPGET, true);
                break;
            case "POST":
                curl_setopt($ch, CURLOPT_POST, true);
                break;
            case "PUT"://使用一个自定义的请求信息来代替"GET"或"HEAD"作为HTTP请求。这对于执行"DELETE" 或者其他更隐蔽的HTT
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
                break;
            case "DELETE":
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
                break;
        }
        //4)在HTTP请求中包含一个"User-Agent: "头的字符串。-----必设
//		curl_setopt($ch, CURLOPT_USERAGENT, 'SSTS Browser/1.0');
//		curl_setopt($ch, CURLOPT_ENCODING, 'gzip');

        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)'); // 模拟用户使用的浏览器
        //5)
        //3.抓取URL并把它传递给浏览器
        $res = curl_exec($ch);
        $result = json_decode($res, true);
        //4.关闭curl资源，并且释放系统资源
        curl_close($ch);
        if (empty($result))
            return $res;
        else
            return $result;
    }

    /**


    /**
     * 检查是否是合法的IP
     * @param $ip
     * @return bool
     */
    public static function isIp($ip)
    {
        if (preg_match('/^((\d|[1-9]\d|2[0-4]\d|25[0-5]|1\d\d)(?:\.(\d|[1-9]\d|2[0-4]\d|25[0-5]|1\d\d)){3})$/', $ip)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 验证手机号
     * @param $mobile
     * @return false|int
     */
    public static function checkMobile($mobile)
    {
        return preg_match('/^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\d{8}$/i', $mobile);
    }

    /**
     * 通过手机号生成api_token
     * @param int $phone
     * @return string
     */
    public static function RandomToken(int $phone)
    {
        if (empty($phone)) {
            return '';
        }
        return hash('sha256', Str::random(48) . md5($phone));
    }

    /**
     * 设置更新登录api_token
     * @param $api_token
     * @param $phone
     * @return false|mixed|string
     */
    public static function SetAndUpToken($api_token, $phone = null)
    {
        $expiredTime = env('REDIS_EXPIRED_LOGIN_TIME');
        if (!empty($phone)) {
            $user = User::where([['phone', $phone]])->first();
            Redis::setex($api_token, $expiredTime, json_encode($user, JSON_UNESCAPED_UNICODE));
        } else {
            //手机是空的更新操作
            $value = Redis::get($api_token);
            Redis::setex($api_token, $expiredTime, $value);
        }
    }

    /***
     * 获取客户端登录用户信息
     * @param $api_token
     * @return void
     */
    public static function getUser($api_token)
    {
        $value = Redis::get($api_token);
        if (!empty($value)) {
            return \GuzzleHttp\json_decode($value, true);
        }
        $user = User::where([['api_token', $api_token]])->first();
        if (!empty($user)) {
            return $user->toArray();
        }
        return [];
    }

    /**
     * 设置更新登录api_token
     * @param $api_token
     * @param $phone
     * @return false|mixed|string
     */
    public static function SetDoctorAndUpToken($api_token, $phone = null)
    {
        $expiredTime = env('REDIS_EXPIRED_LOGIN_TIME');
        if (!empty($phone)) {
            $user = Doctor::where([['account', $phone]])->first();//获取 用户记录
            $user->clinic??"";      //获取 科室分类
            $user->professional??"";//获取 所属职称
            $user->works??"";       //获取 所属工作室
            if ($user->is_admin != 1) {
                $user->works->store_manager = Doctor::where([['work_id', '=', $user->work_id]])->value("real_name");//获取 用户记录
            } else {
                $user->works->store_manager = $user->real_name;
            }
            $user->hidden_phone = substr_replace($user->account, '****', 3, 4);
            self::DoctorPicDeal($user);
            Redis::setex($api_token, $expiredTime, \GuzzleHttp\json_encode($user, JSON_UNESCAPED_UNICODE));
        } else {
            //手机是空的更新操作
            $value = Redis::get($api_token);
            Redis::setex($api_token, $expiredTime, $value);
        }
    }

    /**
     * @param $obj
     * @return mixed
     * 工作室信息图片增加全路径
     */
    public static function DoctorPicDeal(&$obj)
    {
        //科室图片处理
        if (!empty($obj->clinic)) {
            $obj->clinic->HosTclassify_picture = self::AddHost($obj->clinic->classify_picture);
        }
        //工作室处理
        if (!empty($obj->works)) {
            $obj->works->HosTlogo = self::AddHost($obj->works->logo);
            $obj->works->HosTimages = self::AddHost($obj->works->images);
            if (is_array($obj->works->work_detail) && !empty($obj->works->work_detail)) {
                $obj->works->HosTwork_detail = self::ArrayAddHost($obj->works->work_detail);
            }
        }
        //医生图片字段增加全路径

        //多图片处理
        if (is_array($obj->certificate) && !empty($obj->certificate)) {
            $obj->HosTcertificate = self::ArrayAddHost($obj->certificate);
        }
        $obj->HosTprofile = self::AddHost($obj->profile);
        $obj->HosTfront_card = self::AddHost($obj->front_card);
        $obj->HosTbehind_card = self::AddHost($obj->behind_card);
        $obj->HosTlogo = self::AddHost($obj->logo);
        $obj->HosTimages = self::AddHost($obj->images);
        $obj->HosTclassify_picture = self::AddHost($obj->classify_picture);
        return $obj;
    }

    /**
     * @param $array
     * @return array
     */
    public static function ArrayAddHost($array)
    {
        if (is_array($array)) {
            $arr = [];
            foreach ($array as $val) {
                $arr[] = self::AddHost(trim($val));
            }
            return $arr;
        } else {
            return [];
        }
    }

    /**
     * @param $path
     * @return string|void
     * 增加图片全路径
     */
    public static function AddHost($path)
    {
        if (!empty($path) && is_string($path)) {
            return Url::getHttpHost() . 'upload/' . trim($path);
        }
        return "";
    }

    /***
     * 获取医护端登录用户信息
     * @param $api_token
     * @return void
     */
    public static function getDoctorUser($api_token)
    {
        $value = Redis::get($api_token);
        if (!empty($value)) {
            return \GuzzleHttp\json_decode($value, true);
        }
        $user = Doctor::where([['api_token', $api_token]])->first();
        if (!empty($user)) {
            $user->clinic;          //科室分类
            $user->professional;    //所属职称
            $user->works;           //所属工作室
            self::DoctorPicDeal($user);
            $user->hidden_phone = substr_replace($user->account, '****', 3, 4);
            return $user->toArray();
        }
        return [];
    }

    /** 医护端通过api_token获取用户信息
     * @param $api_token
     * @return mixed
     */
    public static function ApiTokenGetDoctorUser($api_token)
    {
        return Doctor::where([['api_token', $api_token]])->first();
    }

    /**医护端检查手机号码是否存在
     * @param $phone
     * @return void
     */
    public static function IssetUser($phone)
    {
        return Doctor::where('account', $phone)->first();
    }

    /**
     * 获取登录后的api_token
     * @param $api_token
     * @return bool
     */
    public static function GetLoginToken($api_token)
    {
        if (Redis::exists($api_token)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 短信认证设置失效时间
     * @param $phone
     * @param $code
     * @return void
     */
    public static function SetSmsvalidator($phone, $code)
    {
        //获取env的配置信息
        //设置手机验证码60秒
        $expiredTime = env('REDIS_EXPIRED_TIME');
        Redis::setex('REDIS_EXPIRED_TIME' . $phone, $expiredTime, $code);
    }

    /**
     * 检查短信失效时间是否过期
     * @param $phone
     * @return string
     */
    public static function GetSmsvalidator($phone)
    {
        $key = 'REDIS_EXPIRED_TIME' . $phone;
        $value = Redis::get($key);
        if (!empty($value)) {
            return $value;
        } else {
            return '';
        }
    }

    /**
     * 短信验证码验证后删除key
     * @param $phone
     * @return string
     */
    public static function UsetSmsCode($phone)
    {
        $key = 'REDIS_EXPIRED_TIME' . $phone;
        Redis::del($key);
    }

    /**
     * 设置重复登录字段用于判断重复登录
     * @param $phone
     * @param $value
     * @return void
     */
    public static function SetLoginToken($phone, $value)
    {
        $expiredTime = env('REDIS_EXPIRED_LOGIN');
        $key = 'REDIS_EXPIRED_TEMP_LOGIN-' . $phone;
        Redis::setex($key, $expiredTime, $value);
    }

    /**
     * 医护端登录设置重复登录字段用于判断重复登录
     * @param $phone
     * @param $value
     * @return void
     */
    public static function SetDoctorLoginToken($phone, $value)
    {
        $expiredTime = env('REDIS_EXPIRED_LOGIN');
        $key = 'REDIS_EXPIRED_TEMP_DOCTOR_LOGIN-' . $phone;
        Redis::setex($key, $expiredTime, $value);
    }

    /**频繁登录获取数据
     * @param $phone
     * @return string
     */
    public static function GetTempLoginToken($phone): string
    {
        //这里key在.env文件定义的
        $key = 'REDIS_EXPIRED_TEMP_LOGIN-' . $phone;
        $value = Redis::get($key);
        if (!empty($value)) {
            return $value;
        } else {
            return '';
        }
    }

    /**
     * 获取图片验证码
     * @param $phone
     * @return array
     */
    public static function CaptchaCode($phone): array
    {
        $captchaBuilder = new CaptchaBuilder();
        $key = 'captcha-' . $phone;
        //$key = 'captcha-' . str_random(15);
        $captcha = $captchaBuilder->build();
        $expiredTime = env('REDIS_EXPIRED_TIME');//过期时间60秒
        Redis::setex($key, $expiredTime, $captcha->getPhrase());
        return [
            'captcha_key' => $key,
            'expired_at' => $expiredTime,
            'captcha_image' => $captcha->inline()
        ];
    }

    /**
     * 获取验证码
     * @return void
     */
    public static function GetCapthCode($phone)
    {
        $key = 'captcha-' . $phone;
        $value = Redis::get($key);
        if (!empty($value)) {
            return $value;
        } else {
            return '';
        }
    }


    /****
     * @return mixed
     * 获取数据库sql
     */
    public static function start()
    {
        return DB::connection()->enableQueryLog();
    }

    public static function ends()
    {
        $logs = DB::getQueryLog();
        dd($logs);
    }


    /***
     * Url加域名
     */
    public function addHostToImage($data)
    {
        if(empty($data)){
            return [];
        }
        if (is_array($data)) {
            $img_data = [];
            foreach ($data as $kk => $vv) {
                $img_data[] = env('APP_URL') . '/upload/' . trim($vv);
            }
            return $img_data;
        } else {
            $img_data = env('APP_URL') . '/upload/' . $data;
            return $img_data;
        }
    }


    /**
     * 迭代器方法，实现无限分类树
     * @param array $array 原始数据包
     * @return array
     */
    public static function buildTree($array)
    {
        if (empty($array)) {
            return [];
        }
        $map = array();
        $fotmatTree = array();
        foreach ($array as &$vo) {
            $map[$vo['id']] = &$vo;
//            $map[$vo['id']]['child'] = array();
        }
        unset($vo);
        foreach ($array as &$item) {
            $parent = &$map[$item['pid']];
            if (empty($parent)) {
                $fotmatTree[] = &$item;
            } else {
                $parent['child'][] = &$item;

            }
        }
        unset($map);
        return $fotmatTree;
    }

    /**
     * 检查是否是base64编码数据
     * @param $str
     * @return bool
     */
    public static function issetBase64($str): bool
    {
        $originalLength = strlen($str);
        // 对于标准Base64编码，长度应该是4的倍数；对于URL安全的Base64编码，长度应该是3的倍数
        return $originalLength % 4 === 0 || $originalLength % 3 === 0;
    }


    /**
     * @param $str
     * @return array处理字符串编数组
     */
    public static function handelString($str)
    {
        if (empty($str)) {
            return [];
        }
        $left = ltrim($str, "[");
        $string = rtrim($left, "]");
        $array = explode(',', $string);
        $result = [];
        foreach ($array as $k => $v) {
            if ($v !== null && $v !== "") {
                $result[] = trim($v);
            }
        }
        return $result;
    }

    /**
     * 时间差计算
     *
     * @param Timestamp $time 时间差
     * @return String Time Elapsed
     * @author jakehu (http://www.111cn.net/)
     */
    public static function time2Units($time)
    {
        $year = floor($time / 60 / 60 / 24 / 365);
        $time -= $year * 60 * 60 * 24 * 365;
        $month = floor($time / 60 / 60 / 24 / 30);
        $time -= $month * 60 * 60 * 24 * 30;
        $week = floor($time / 60 / 60 / 24 / 7);
        $time -= $week * 60 * 60 * 24 * 7;
        $day = floor($time / 60 / 60 / 24);
        $time -= $day * 60 * 60 * 24;
        $hour = floor($time / 60 / 60);
        $time -= $hour * 60 * 60;
        $minute = floor($time / 60);
        $time -= $minute * 60;
        $elapse = '';
        $unitArr = array('年前' => 'year', '个月前' => 'month', '周前' => 'week', '天前' => 'day',
            '小时前' => 'hour', '分钟前' => 'minute', '秒前' => 'second');
        foreach ($unitArr as $cn => $u) {
            if ($year > 0) {//大于一年显示年月日
                $elapse = date('Y/m/d', time() - $time);
                break;
            } else if ($$u > 0) {
                $elapse = $$u . $cn;
                break;
            }
        }
        return $elapse;
    }

    /**
     * @param $param
     * 取环信获用户名称和密码
     */
    public static function getUserNameForIm($param)
    {
        if ($param['type'] == 1) {
            $users = User::where([['id', '=', $param['user_id']]])->first();
            $username = 'user_' . config("omnipay.Im.salt") . $users->id;
            $password = md5('user' . config("omnipay.Im.salt") . $users->id);
        } elseif ($param['type'] == 2) {
            $users =  Doctor::where([['id', '=', $param['user_id']]])->first();
            $username = 'doctor_' . config("omnipay.Im.salt") . $users->id;
            $password = md5('doctor' . config("omnipay.Im.salt") . $users->id);
        }
        $data['username']  = $username;
        $data['password']  = $password;
        return $data;
    }
    /**
     * @return \string[][]
     * 物流公司code
     */
    public static function logis_code()
    {
        return [
            'shunfeng'=>"顺丰速运",
            'jd'=>"京东物流",
            'yuantong'=>"圆通速递",
            'shentong'=>"申通快递",
            'jtexpress'=>"极兔速递",
            'zhongtong'=>"中通快递",
            'yunda'=>"韵达快递",
            'youzhengguonei'=>"邮政快递包裹",
            'ems'=>"EMS",
            'debangkuaidi'=>"德邦快递",
            'danniao'=>"菜鸟速递",
            'debangwuliu'=>"德邦",
        ];
    }
}
